using System.Drawing;

using SharpWind.Input;
using Microsoft.DirectX.Direct3D;

namespace SharpWind.Gui.Controls
{
	public abstract class ButtonBase : Control
	{
		protected enum State
		{
			Normal,
			Over,
			Down,
			Disabled
		}

		protected State curentState = State.Normal;

		protected string control = string.Empty;

		protected SizeF cornerSize = new SizeF( 0, 0 );

		protected SizeF borderVerticalSize = new SizeF( 0, 0 );

		protected SizeF borderHorizontalSize = new SizeF( 0, 0 );

		protected SizeF backgroundSize = new SizeF( 0, 0 );

		private State lastState = State.Normal;

		protected bool mouseDown = false;

		public ButtonBase( string control )
		{
			this.control = control;
		}

		internal override void Render()
		{
			if( Visible )
			{
				Engine.Instance.Renderer.GuiSprite.Begin( SpriteFlags.AlphaBlend );

				RenderCorners( this.curentState.ToString() );
				RenderBorder( this.curentState.ToString() );
				RenderBackground( this.curentState.ToString() );

				Engine.Instance.Renderer.GuiSprite.End();
			}
		}

		internal override void MouseMove( MouseEventArgs e )
		{
			if( Enabled && Visible )
			{
				RectangleF rectangle = new RectangleF( Location, Size );
				if( rectangle.Contains( new PointF( e.AbsX, e.AbsY ) ) )
				{
					this.curentState = State.Over;
				}
				else
				{
					this.curentState = State.Normal;
				}
			} 
		} 

		internal override void MouseDown( MouseEventArgs e )
		{
			if( Enabled && !this.mouseDown && Visible )
			{
				RectangleF rectangle = new RectangleF( Location, Size );
				if( rectangle.Contains( new PointF( e.AbsX, e.AbsY ) ) )
				{
					this.lastState   = this.curentState;
					this.mouseDown   = true;
					this.curentState = State.Down;

					OnMouseDown();
				}
			}
		}

		internal override void MouseUp( MouseEventArgs e )
		{
			if( Enabled && this.mouseDown && Visible )
			{
				this.mouseDown   = false;
				this.curentState = lastState;

				OnMouseUp();
			}
		}

		protected virtual void OnMouseDown()
		{
			
		}

		protected virtual void OnMouseUp()
		{
			
		}

		private void RenderCorners( string state )
		{
			Theme theme = Engine.Instance.Scene.Controls.Theme;
			Theme.Control button = theme.Controls[this.control];

			// Top, Left
			Theme.Control.Element element = button.Elements[state + "TopLeftCorner"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													cornerSize, new PointF( location.X, location.Y ), element.Color );

			// Top, Right
			element = button.Elements[state + "TopRightCorner"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													cornerSize,
													new PointF( location.X + borderHorizontalSize.Width + cornerSize.Width,
																location.Y ), element.Color );

			// Bottom, Left
			element = button.Elements[state + "BottomLeftCorner"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													cornerSize,
													new PointF( location.X,
																location.Y + borderVerticalSize.Height + cornerSize.Height ),
													element.Color );

			// Bottom, Right
			element = button.Elements[state + "BottomRightCorner"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													cornerSize,
													new PointF( location.X + borderHorizontalSize.Width + cornerSize.Width,
																location.Y + borderVerticalSize.Height + cornerSize.Height ),
													element.Color );
		}

		private void RenderBorder( string state )
		{
			Theme theme = Engine.Instance.Scene.Controls.Theme;
			Theme.Control button = theme.Controls[this.control];

			// Top
			Theme.Control.Element element = button.Elements[state + "TopBorder"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													borderHorizontalSize, new PointF( location.X + cornerSize.Width, location.Y ),
													element.Color );

			// Right
			element = button.Elements[state + "RightBorder"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													borderVerticalSize,
													new PointF( location.X + cornerSize.Width + borderHorizontalSize.Width,
																location.Y + cornerSize.Height ), element.Color );
			// Bottom
			element = button.Elements[state + "BottomBorder"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													borderHorizontalSize,
													new PointF( location.X + cornerSize.Width,
																location.Y + cornerSize.Height + borderVerticalSize.Height ),
													element.Color );

			// Left
			element = button.Elements[state + "LeftBorder"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													borderVerticalSize, new PointF( location.X, location.Y + cornerSize.Height ),
													element.Color );
		}

		private void RenderBackground( string state )
		{
			Theme theme = Engine.Instance.Scene.Controls.Theme;
			Theme.Control button = theme.Controls[this.control];

			Theme.Control.Element element = button.Elements[state + "Background"];
			Engine.Instance.Renderer.GuiSprite.Draw2D( theme.Texture.D3DTexture,
													new Rectangle( element.X, element.Y, element.Width, element.Height ),
													backgroundSize,
													new PointF( location.X + cornerSize.Width, location.Y + cornerSize.Height ),
													element.Color );
		}

		private void RecalculateCorners()
		{
			Theme theme = Engine.Instance.Scene.Controls.Theme;
			Theme.Control button = theme.Controls[this.control];

			Theme.Control.Element element = button.Elements[this.curentState.ToString() + "TopLeftCorner"];

			cornerSize.Width  = element.Width;
			cornerSize.Height = element.Height;
		}

		private void RecalculateBorder()
		{
			//Horizotnal
			borderHorizontalSize.Width  = Size.Width - ( 2f * cornerSize.Width );
			borderHorizontalSize.Height = cornerSize.Height;

			//Vertical
			borderVerticalSize.Width  = cornerSize.Width;
			borderVerticalSize.Height = Size.Height - ( 2f * cornerSize.Height );
		}

		private void RecalculateBackground()
		{
			backgroundSize.Width  = Size.Width  - ( 2 * borderVerticalSize.Width );
			backgroundSize.Height = Size.Height - ( 2 * borderHorizontalSize.Height );
		}

		public override SizeF Size
		{
			get
			{
				return this.size;
			}
			set
			{
				if( value != this.size )
				{
					this.size = value;
					RecalculateCorners();
					RecalculateBorder();
					RecalculateBackground();
				}
			}
		}

		/// <summary>
		/// Enabled
		/// </summary>
		/// <returns>Bool</returns>
		public override bool Enabled
		{
			get
			{
				return this.enabled;
			} // get
			set
			{
				this.enabled     = value;
				this.curentState = ( Enabled ) ? State.Normal : State.Disabled;
			} // set
		} // Enabled
	}
}
